#pragma once
//线程池的实现（单例模式）
#include<pthread.h>
#include<iostream>
#include<queue>
#include"Task.hpp"
#define THREAD_NUM 5
int threadid[THREAD_NUM];
class ThreadPool
{   private:
    ThreadPool()
    :num_(THREAD_NUM)
    {
        //初始化锁和条件变量
        pthread_mutex_init(&lock_,nullptr);
        pthread_cond_init(&cond_,nullptr);
    }
    ThreadPool(const ThreadPool&)=delete;
    ThreadPool&operator=(const ThreadPool&)=delete;
    static ThreadPool*ptr_;//需要类外定义//用来获取单例
    static pthread_mutex_t intanse_lock;//用来给获取实例上锁
    private:
    int num_;//线程个数
    std::queue<Task> task_queue;//任务队列，"交易场所"
    pthread_mutex_t lock_;//锁
    pthread_cond_t cond_;//条件变量
    void CondWait()
    {
        //到条件变量的等待队列里等
        pthread_cond_wait(&cond_,&lock_);//等待的同时会释放锁
    }
    void WakeUp()
    {
        //唤醒对应等待队列里的线程
        pthread_cond_signal(&cond_);//唤醒的同时会去获取锁
    }
    bool IsEmpty()
    {
        //队列判空
        return task_queue.empty();
    }
    void Lock()
    {
        //上锁
        pthread_mutex_lock(&lock_);
    }
    void Unlock()
    {
        //解锁
        pthread_mutex_unlock(&lock_);
    }
 
    public:
    static ThreadPool*GetInstance()//获取实例
    {
        if(ptr_==nullptr)
        {
            pthread_mutex_lock(&intanse_lock);
            if(ptr_==nullptr)
            {
                ptr_=new ThreadPool();
                ptr_->InitPool();
            }
            pthread_mutex_unlock(&intanse_lock);
        }
        return ptr_;
    }
    static void*HandlerRoutine(void*argv)//因为类内默认存在this指针，static没有this指针
    {
        ThreadPool*tp=static_cast<ThreadPool*>(argv);
        //线程要干嘛呢？获取任务->处理任务
        lg(DEBUG,"thread is already work!");
        while(true)
        {
               Task t;
        tp->Pop(t);//获取任务
        t();//执行任务
    
        }
     
    }
    void InitPool()
    {
        //线程池初始化
        for(int i=0;i<THREAD_NUM;i++)
        {
            pthread_t tid;
           pthread_create(&tid,nullptr,HandlerRoutine,this);//要访问的队列（交易场所）在当前对象里
           threadid[i]=tid;
            lg(DEBUG,"create thread success ,tid is%d",tid);

        }
    }
    void Push(const Task&t)
    {
        Lock();
        task_queue.push(t);
        WakeUp();
        Unlock();
    }
    void Pop(Task&t)//t输出型参数
    {
        Lock();
        while(IsEmpty())//防止伪唤醒
        {
            CondWait();
        }
        t=task_queue.front();
        task_queue.pop();
        Unlock();
    }
    ~ThreadPool()
    {
        //销毁锁和条件变量
        pthread_mutex_destroy(&lock_);
        pthread_cond_destroy(&cond_);
        for(auto &e:threadid)
        {
            pthread_join(e,nullptr);
        }
    }
};
ThreadPool* ThreadPool::ptr_=nullptr;
pthread_mutex_t ThreadPool::intanse_lock=PTHREAD_MUTEX_INITIALIZER;//定义全局锁，不需要销毁、初始化